package com.app.reptile.tasks;

import com.app.reptile.base.MybatisSingleton;
import com.app.reptile.constant.CrawlerConstant;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.ibatis.session.SqlSession;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Objects;

/**
 * 定时系统通知
 *
 （1）0/2 * * * * ?   表示每2秒 执行任务

  （1）0 0/2 * * * ?    表示每2分钟 执行任务

  （1）0 0 2 1 * ?   表示在每月的1日的凌晨2点调整任务

  （2）0 15 10 ? * MON-FRI   表示周一到周五每天上午10:15执行作业

  （3）0 15 10 ? 6L 2002-2006   表示2002-2006年的每个月的最后一个星期五上午10:15执行作

  （4）0 0 10,14,16 * * ?   每天上午10点，下午2点，4点

  （5）0 0/30 9-17 * * ?   朝九晚五工作时间内每半小时

  （6）0 0 12 ? * WED    表示每个星期三中午12点

  （7）0 0 12 * * ?   每天中午12点触发

  （8）0 15 10 ? * *    每天上午10:15触发

  （9）0 15 10 * * ?     每天上午10:15触发

  （10）0 15 10 * * ?    每天上午10:15触发

  （11）0 15 10 * * ? 2005    2005年的每天上午10:15触发

  （12）0 * 14 * * ?     在每天下午2点到下午2:59期间的每1分钟触发

  （13）0 0/5 14 * * ?    在每天下午2点到下午2:55期间的每5分钟触发

  （14）0 0/5 14,18 * * ?     在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

  （15）0 0-5 14 * * ?    在每天下午2点到下午2:05期间的每1分钟触发

  （16）0 10,44 14 ? 3 WED    每年三月的星期三的下午2:10和2:44触发

  （17）0 15 10 ? * MON-FRI    周一至周五的上午10:15触发

  （18）0 15 10 15 * ?    每月15日上午10:15触发

  （19）0 15 10 L * ?    每月最后一日的上午10:15触发

  （20）0 15 10 ? * 6L    每月的最后一个星期五上午10:15触发

  （21）0 15 10 ? * 6L 2002-2005   2002年至2005年的每月的最后一个星期五上午10:15触发

  （22）0 15 10 ? * 6#3   每月的第三个星期五上午10:15触发

 */
public abstract class AbstractTask implements Job{

	protected Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 执行任务内容
	 */
    protected abstract void start() throws Exception;
	
	private SqlSession sqlSession = null;
	
	public void setSqlSession(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
	}
	public SqlSession getSqlSession() {
		return sqlSession;
	}
	
	private void initBean() {
		Field[] fields = this.getClass().getDeclaredFields();
		for(Field field : fields) {
			String name = field.getType().getName();
			if (name.startsWith("com.mybatis.mapper")) {
				try {
					Object object = PropertyUtils.getProperty(this, field.getName());
					if (Objects.isNull(object)) {
						sqlSession = MybatisSingleton.getInstance().getSqlSession();
//						logger.info("加载mapper:{}",field.getType());
						Object value = sqlSession.getMapper(field.getType());
						PropertyUtils.setProperty(this, field.getName(), value);
					}
				} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
					e.printStackTrace();
				}
			}
		}
	}
	/**
	 * 真正执行任务
	 */
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		String key = this.getClass().getName();
		try {
			Boolean run = CrawlerConstant.STATUS.putIfAbsent(key, Boolean.TRUE);
			logger.trace("当前调度状态:{}----{}",key,run);
			if (Objects.nonNull(run) && run) {
				return;
			}
			initBean();
			start();
			CrawlerConstant.STATUS.put(key, Boolean.FALSE);
		} catch (Exception e) {
			logger.error("任务执行失败!",e);
			CrawlerConstant.STATUS.put(key, Boolean.FALSE);
		}
	}
	/**
	 * 真正执行任务
	 */
	public void execute(){
		try {
			execute(null);
		} catch (JobExecutionException e) {
			logger.error("任务执行失败!",e);
		}
	}

	/**
	 * 根路径
	 */
	protected static final File ROOT = new File("a_data_");
}
